package com.example.springlog.util;

import com.example.springlog.entity.DesensitiveRule;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Description: 脱敏工具类
 * @Author: 刘超
 * @Date: 2023-06-01 11:24
 */
public class DesensitiveUtil {

    /**
     * 规则正则表达式
     */
    private final static String RULE_REGEX = "^(\\W)([<>])(\\(\\d+\\,\\d+\\))|(\\d+\\,\\d+)$";

    /**
     * 将字符串从某个位置开始到结束位置替换为指定字符
     *
     * @param value   源字符串
     * @param start   起始位置
     * @param end     结束位置
     * @param replace 替换字符
     * @return
     */
    public static String replace(String value, int start, int end, char replace) {
        if (value == null || value.length() == 0) {
            return value;
        }
        start = Math.max(start, 0);
        end = Math.min(end, value.length());
        char[] chars = value.toCharArray();
        for (int i = start; i < end; ++i) {
            chars[i] = replace;
        }
        return new String(chars);
    }

    /**
     * 根据替换规则替换字符串敏感数据为*
     *
     * @param value 源字符串
     * @param rule  替换规则
     * @return
     */
    public static String replaceByRule(String value, String rule) {
        if (rule == null) {
            return value;
        }
        Matcher matcher = Pattern.compile(RULE_REGEX).matcher(rule);
        int start;
        int end;
        String key;
        String[] position;
        if (matcher.find()) {
            key = matcher.group(1);
            if (key != null) {
                if (value.contains(key)) {
                    String[] splitValue = value.split(key);
                    String direction = matcher.group(2).trim();
                    position = matcher.group(3).replace("(", "").replace(")", "").trim().split(",");
                    start = Integer.parseInt(position[0]);
                    end = Integer.parseInt(position[1]);
                    if (">".equals(direction)) {
                        int offset = splitValue[0].length() + 1;
                        start = start + offset;
                        end = end + offset;
                    }
                    return replace(value, start , end , '*');
                }
            } else {
                position = matcher.group(0).trim().split(",");
                start = Integer.parseInt(position[0]);
                end = Integer.parseInt(position[1]);
                return replace(value, start, end, '*');
            }
        }
        return value;
    }

    /**
     * 根据规则匹配字符串并进行替换
     * @param message
     * @param rules
     * @return
     */
    public static String desensitive(String message, List<DesensitiveRule> rules) {
        for (DesensitiveRule rule :rules) {
            Matcher matcher = Pattern.compile(rule.getRegex()).matcher(message);
            StringBuffer sb = new StringBuffer();
            boolean find = false;
            while (matcher.find()) {
                find = true;
                matcher.appendReplacement(sb, replaceByRule(matcher.group(), rule.getRule()));
            }
            matcher.appendTail(sb);
            if (find && sb.length() != 0) {
                message = sb.toString();
            }
        }
        return message;
    }
}
